//package com.quanshi.jingdian.utils;
//
//import com.quanshi.common.utils.bean.BeanUtils;
//import com.quanshi.jingdian.constants.SetConstants;
//import com.quanshi.jingdian.domain.*;
//import com.quanshi.jingdian.domain.vo.EditElectricityResultVo;
//import com.quanshi.jingdian.domain.vo.JdElectricityRecordsVo;
//import com.quanshi.jingdian.domain.vo.UpdateElectricityUserVo;
//import lombok.Data;
//import lombok.extern.slf4j.Slf4j;
//
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.OutputStream;
//import java.math.BigDecimal;
//import java.math.RoundingMode;
//import java.net.ServerSocket;
//import java.net.Socket;
//import java.util.*;
//
//
///**
// * 通信长连接  端口业务处理
// *
// * @author quanshi
// * @date 2023-02-22
// */
//
//@Slf4j
//@Data
//public class PortListener implements Runnable {
//
//    // 当前使用的端口
//    private int port;
//
//    // 当前使用的端口
//    private boolean running;
//
//    private JdRelaying relaying;
//
//    // 端口管理器
//    private PortListenerManager manager;
//
//    // 通信长连接
//    private ServerSocket serverSocket;
//
//    // 端口监控
//    private Socket socket;
//
//    private Boolean isSocket = false;
//
//    // 以下是业务数据存储
//
//    // 存储已建立的连接
//    private List<Socket> connectedSockets = new ArrayList<>();
//    //所有的棒子基本信息
//    private Map<String, JdElectricity> electricityMap = new HashMap<>();
//    //所有的工位信息
//    private Map<Long, JdStation> stationMap = new HashMap<>();
//    //所有的产品信息
//    private Map<String, JdProduct> productMap = new HashMap<>();
//    //新增数据的list
//    private List<JdElectricityRecords> list = new ArrayList<>();
//    //所有的棒子正在修改的参数判断
//    private Map<String, EditElectricityResultVo> editElectricityResultMap = new HashMap<>();
//
//    public PortListener(int port,
//                        PortListenerManager manager) {
//        this.port = port;
//        this.running = true;
//        this.manager = manager;
//    }
//
//    @Override
//    public void run() {
//        try {
//            serverSocket = new ServerSocket(port);
//            log.info("开始监听端口：{}", port);
//        } catch (IOException e) {
//            log.info("通信长连接出现错误：{}", port);
//        }
//        while (running) {
//            try {
//                socket = serverSocket.accept();
//                if (!socket.isClosed() && socket.isConnected()) {
//                    // 将新连接加入集合
//                    connectedSockets.add(socket);
//                    // 接收连接信息
//                    getData(socket);
//                } else {
//                    log.info("无效的连接");
//                    // 关闭所有已建立的连接
//                    closeAllConnections();
//                }
//            } catch (IOException e) {
//                if (running) {
//                    log.info("监听端口错误：{}", port);
//                    // 关闭所有已建立的连接
//                    closeAllConnections();
//                    // 重新创建服务器套接字
//                    recreateServerSocket();
//                }
//            }
//        }
//    }
//
//     // 关闭所有已建立的连接
//    private void closeAllConnections() {
//        for (Socket clientSocket : connectedSockets) {
//            try {
//                clientSocket.close();
//            } catch (IOException ex) {
//                log.info("关闭连接报错");
//            }
//        }
//        connectedSockets.clear(); // 清空连接集合
//        try {
//            if (socket != null && !socket.isClosed()) {
//                socket.close();
//            }
//        } catch (IOException ex) {
//            log.info("关闭套接字报错");
//        }
//    }
//
//    // 重新创建服务器套接字
//    private void recreateServerSocket() {
//        try {
//            serverSocket.close();
//        } catch (IOException e) {
//            log.info("关闭服务器套接字报错");
//        }
//        try {
//            serverSocket = new ServerSocket(port);
//            log.info("重新创建服务器套接字");
//        } catch (IOException e) {
//            log.info("重新创建服务器套接字报错");
//        }
//    }
//
//
//    /**
//     * 停止端口方法
//     */
//    public void stopPort() {
//        try {
//            this.running = false;
//            if (Objects.nonNull(serverSocket)) {
//                serverSocket.close();
//            } else {
//                log.info("serverSocket  通信长连接为空");
//            }
//            // 关闭所有已建立的连接
//            for (Socket clientSocket : connectedSockets) {
//                clientSocket.close();
//            }
//            log.info("成功停用端口：{}", port);
//        } catch (IOException e) {
//            log.info("停止端口失败：{}", port);
//        }
//    }
//
//    /**
//     * 解析每一次接收的数据
//     */
//    private void getData(Socket socket) throws IOException {
//
//        try {
//            socket.setSoTimeout(4000);
//            InputStream inputStream = socket.getInputStream();
//            OutputStream outputStream = socket.getOutputStream();
//            byte[] buffer = new byte[1024];
//            int bytesRead;
//            StringBuilder sb = new StringBuilder();
//            while ((bytesRead = inputStream.read(buffer)) != -1) {
//                sb.append(bytesToHexString(buffer, bytesRead));
//                String hexData = sb.toString().trim().replace(" ", "");
//
//                int headerCount = countOccurrences(hexData, "FAFBFC");
//                int tailCount = countOccurrences(hexData, "CFBFAF");
//
//                if (headerCount == 1 && tailCount == 1) {
//                    parseResponse(hexData, sb, outputStream);
//                } else if (headerCount > 1 && tailCount > 1){
//                    // 找到第一个出现的字符串"FAFBFC"
//                    int startIndex = hexData.indexOf("FAFBFC");
//                    // 在startIndex之后找到字符串"CFBFAF"的索引
//                    int endIndex = hexData.indexOf("CFBFAF", startIndex);
//                    // 截取字符串
//                    hexData = hexData.substring(startIndex, endIndex + 6); // 加上6是为了包含"EBFEFAE"
//                    parseResponse(hexData, sb, outputStream);
//                    log.info("数据异常，当前端口：{}，截取数据：{}", socket.getLocalPort(), hexData);
//                }else {
//                    log.info("数据异常，当前端口：{}，解析数据：{}", socket.getLocalPort(), hexData);
//                }
//            }
//        } catch (IOException e) {
//            log.info("连接断开，当前端口：{}", socket.getLocalPort());
//        } finally {
//            closeAllConnections();
//        }
//    }
//
//    // 需要向设备发送 “EAEBEC0A5500000000B2CEBEAE” 表示已经接收到数据包
//    private void parseResponse(String str, StringBuilder sb, OutputStream outputStream) throws IOException {
//        //  解析传输过来的数据包
//        processPacket(str);
//        // 清空StringBuilder
//        sb.setLength(0);
//
//        //  将port端口存入redis  以此通过redis查询端口是否接收到数据包
//        manager.redisUtils.set(SetConstants.RELAYING + socket.getLocalPort(), String.valueOf(socket.getLocalPort()), SetConstants.relayingExpiration);
//
//        //发送指令  约定指令
//        String sendData = "EAEBEC0A5500000000B2CEBEAE";
//        outputStream.write(hexStringToByteArray(sendData));
//        outputStream.flush();
//    }
//
//
//    // 辅助方法：将十六进制字符串转换为字节数组
//    public byte[] hexStringToByteArray(String hex) {
//        int len = hex.length();
//        byte[] dataBytes = new byte[len / 2];
//        for (int i = 0; i < len; i += 2) {
//            dataBytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
//                    + Character.digit(hex.charAt(i + 1), 16));
//        }
//        return dataBytes;
//    }
//
//    private String bytesToHexString(byte[] bytes, int length) {
//        StringBuilder sb = new StringBuilder();
//        for (int i = 0; i < length; i++) {
//            sb.append(String.format("%02X ", bytes[i]));
//        }
//        return sb.toString();
//    }
//
//    /**
//     * 数据包解析方法
//     */
//    private void processPacket(String data) {
//
//        // 以下是数据包解析示例
//
//        if (Objects.equals(data, "FAFBFC0008FF0A01CFBFAF")) {
//            log.info("没有棒子连接：{}", data);
//            return;
//        }
//
//        int index = 0;
//        while (index < data.length() - 10) {
//            // 解析起始针头 FA FB FC
//            String header = data.substring(index, index + 6);
//
//            if (!Objects.equals("FAFBFC", header)) {
//                log.info("起始针头解析失败,解析数据：{}", data);
//                return;
//            }
////            System.out.println("起始针头: " + header);
//            index += 6;
//
//            // 解析字节数
//            String byteCountString = data.substring(index, index + 4);
//            int byteCount = Integer.parseInt(byteCountString, 16) * 2 - 14;
////            System.out.println("后面的字节数: " + byteCount + " Byte");
//            index += 4;
//
//            while (byteCount > 0) {
//                //  存储值使用
//                JdElectricityRecordsVo records = new JdElectricityRecordsVo();
//
//                //中继端口
//                records.setRelayingPort(getPort());
//
//                // 解析SSE地址 （设备唯一id）
//                String address = data.substring(index, index + 4);
//                //将十六进制内容转换成十进制内容
//                String addressID = base16Conversion10(address);
//                records.setSoleId(addressID);
//                index += 4;
//
//                // 解析设备启/停状态
//                String status = data.substring(index, index + 2);
//                records.setEquipmentStatus(status);
//                //判断是否存在修改指令  如果有就进行判断
//                parseUpDataElectricity(1, upRecord);
//                index += 2;
//
//                // 解析设备类型和工作状态
//                String deviceStatus = data.substring(index, index + 2);
//                records.setEquipmentType(String.valueOf(deviceStatus.charAt(0)));
//                records.setJobStatus(String.valueOf(deviceStatus.charAt(1)));
////                parseDeviceStatus(deviceStatus);
//                index += 2;
//
//                // 解析工作模式
//                String workMode = data.substring(index, index + 2);
//                records.setWorkingMode(parseWorkMode(workMode));
//                records.setType(parseProductStatus(records));
//                //判断是否存在修改指令  如果有就进行判断
//                parseUpDataElectricity(2, upRecord);
//                index += 2;
//
//                // 解析工作频率
//                String frequencyString = data.substring(index, index + 2);
////                int frequency = Integer.parseInt(frequencyString, 16) / 10;
//                long frequency = Long.parseLong(frequencyString, 16);
//                BigDecimal frequencyBigDecimal = BigDecimal.valueOf(frequency).divide(BigDecimal.TEN, 2, RoundingMode.HALF_EVEN);
//                records.setFrequency(frequencyBigDecimal);
////                System.out.println("工作频率: " + frequency + " Hz");
//                //判断是否存在修改指令  如果有就进行判断
//                parseUpDataElectricity(3, upRecord);
//                index += 2;
//
//                // 解析占空比
//                String dutyCycleString = data.substring(index, index + 2);
////                int dutyCycle = Integer.parseInt(dutyCycleString, 16);
//                long dutyCycle = Long.parseLong(dutyCycleString, 16);
//                BigDecimal dutyCycleDecimal = BigDecimal.valueOf(dutyCycle);
//                records.setDutyCycle(dutyCycleDecimal);
////                System.out.println("占空比: " + dutyCycle + "%");
//                //判断是否存在修改指令  如果有就进行判断
//                parseUpDataElectricity(4, upRecord);
//                index += 2;
//
//                // 解析正电压
//                String positiveVoltageString = data.substring(index, index + 2);
////                int positiveVoltage = Integer.parseInt(positiveVoltageString, 16) / 10;
//                long positiveVoltage = Long.parseLong(positiveVoltageString, 16);
////                System.out.println("正电压: " + positiveVoltage + " kV");
//                index += 2;
//
//                // 解析负电压
//                String negativeVoltageString = data.substring(index, index + 2);
////                int negativeVoltage = Integer.parseInt(negativeVoltageString, 16) / 10;
//                long negativeVoltage = Long.parseLong(negativeVoltageString, 16);
////                System.out.println("负电压: " + negativeVoltage + " kV");
//                index += 2;
//
//
//
//                // 设备业务处理
//
//
//
//                // 解析预留字段 (修改指令 正电压判断)
//                String upPositiveVoltageString = data.substring(index, index + 2);
//                long upPositiveVoltage = Long.parseLong(upPositiveVoltageString, 16);
//                index += 2;
//
//                // 解析预留字段 (修改指令 负电压判断)
//                String upNegativeVoltageString = data.substring(index, index + 2);
//                long upNegativeVoltage = Long.parseLong(upNegativeVoltageString, 16);
//                index += 2;
//
//                // 解析隔断字符
////                String delimiter = data.substring(index, index + 4);
////                System.out.println("隔断字符: " + delimiter);
//                index += 4;
//
//                byteCount -= 26;
//            }
//        }
//
//        // 解析异或校验和软件版本
////        String checksumAndVersion = data.substring(data.length() - 8);
////        String checksum = checksumAndVersion.substring(0, 2);
////        String softwareVersion = checksumAndVersion.substring(4);
////        System.out.println("异或校验: " + checksum);
////        System.out.println("软件版本: " + softwareVersion);
//
//        // 解析结束针尾
////        String tail = data.substring(data.length() - 6);
////        System.out.println("结束针尾: " + tail);
//    }
//
//    /**
//     * 查找字符串是否在使用的字符串中出现
//     */
//    private int countOccurrences(String str, String pattern) {
//        int count = 0;
//        int index = 0;
//        while ((index = str.indexOf(pattern, index)) != -1) {
//            count++;
//            index += pattern.length();
//        }
//        return count;
//    }
//
//    /**
//     * 接收到更新通知后执行的操作
//     */
//    public void update() {
//
//        //  需要使用的数据 从数据库中进行更新
//
//    }
//
//    /**
//     * 修改设备参数
//     */
//    public void sendData(UpdateElectricityUserVo electricityUserVo) {
//        try {
//            // 获取输出流
//            OutputStream outputStream = socket.getOutputStream();
//            if (Objects.nonNull(outputStream)) {
//                outputStreamWrite(electricityRecords, electricityUserVo, outputStream);
//            } else {
//                log.info("没有设备连接");
//            }
//        } catch (IOException ignored) {
//            log.info("棒子参数修改时发生错误，端口：{}  棒子参数：{}", port, electricityUserVo);
//        }
//    }
//
//    /**
//     * 修改设备参数 方法
//     */
//    private void outputStreamWrite(JdElectricityRecordsVo records, UpdateElectricityUserVo electricityUser, OutputStream outputStream) {
//        //将十进制唯一id转换成十六进制
//        String soleId = base10Conversion16(electricityUser.getSoleId());
//
//        //  以下 代码示例
//        if (Objects.nonNull(electricityUser.getEquipmentStatus()) && !Objects.equals(electricityUser.getEquipmentStatus(), records.getEquipmentStatus())) {
//            /* 设备状态;当前设备启/停状态：00-启动，01-停止 */
//            StringBuilder data = new StringBuilder();
//            data.append("EAEBEC0AC5");
//            data.append(soleId);
//            data.append("00");
//            data.append(electricityUser.getEquipmentStatus());
//            String xorCheck = XorCheckUtil.getXorCheck(data.toString());
//            data.append(xorCheck);
//            data.append("CEBEAE");
//            try {
//                // 发送数据
//                outputStream.write(hexStringToByteArray(data.toString()));
//                // 刷新缓冲区，将数据立即写入
//                outputStream.flush();
//                EditElectricityResultVo editElectricityResultVo = new EditElectricityResultVo().convertToEditElectricityResultVo(electricityUser);
//                editElectricityResultVo.setStatusType(1, electricityUser.getEquipmentStatus(), SetConstants.equipmentTime);
//                editElectricityResultMap.put(editElectricityResultVo.getSoleType(), editElectricityResultVo);
//                Thread.sleep(SetConstants.delayTime);
//                log.info("设备状态修改值为：{}", data.toString());
//            } catch (IOException e) {
//                log.info("棒子参数中->设备状态<-出现错误，端口：{}  棒子参数：{}", port, electricityUser);
//            } catch (InterruptedException e) {
//                log.info("->设备状态<-延时操作失败，端口：{}, 参数：{}", port, electricityUser);
//            }
//        }
//        //  以上 代码示例
//
//    }
//
//    /**
//     * 将十六进制内容转换成十进制内容
//     */
//    public static String base16Conversion10(String str) {
//        String decimal = String.valueOf(Integer.parseInt(str, 16));
//        return String.format("%5s", decimal).replace(' ', '0');
//    }
//
//    /**
//     * 将十进制内容转换成十六进制内容
//     */
//    public static String base10Conversion16(String str) {
//        int frequencyInt = Integer.parseInt(str);
//        if (frequencyInt < 1 || frequencyInt > 65535) {
//            throw new IllegalArgumentException("进制转换所需的参数为1 ~ 65535之间的整数");
//        }
//        return String.format("%04X", frequencyInt);
//    }
//
//}
